home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
Other Langs
/
Tickle-4.0 (tcl)
/
src
/
tclMac.c
< prev
next >
Wrap
Text File
|
1993-11-21
|
66KB
|
2,905 lines
/*
** This source code was written by Tim Endres
** Email: time@ice.com.
** USMail: 8840 Main Street, Whitmore Lake, MI 48189
**
*/
#pragma segment TCL
#include <resources.h>
#include <memory.h>
#include <files.h>
#include <GestaltEqu.h>
#include <string.h>
#include <packages.h>
#include <folders.h>
#include <aliases.h>
#include <ToolUtils.h>
#include <errors.h>
#include <stdarg.h>
#include <Folders.h>
#include <Sound.h>
#include <Traps.h>
#include "tcl.h"
#include "tclMac.h"
#include "XTCL.h"
#include "stat.h"
#include "version.h"
char *tcl_check_path_termination( char *path );
/*
** NOTE - _tclmac_user_interrupt_
** The following tclMac variable is used to allow the
** application to interrupt the tcl evaluation process.
** If this variable is set to 1, by any function, then
** the next invocation of command parsing within Tcl_Eval()
** will cause the interpretation to halt and the message
** "*** user interrupt ***" to be added to the result.
*/
int _tclmac_user_interrupt_ = 0;
/*
** NOTE - _tclmac_apprenum_
** The following tclMac variable is set by the call to
** Tcl_InitMacintoshOnce(). It is used to determine the
** path to the application, as well as its name to set
** the corresponding environment variables. It is also
** used by the Mac_EvalResource() command to locate
** resources in the application resource fork.
**
** Further use of this variable is deprecated!
*/
static short _tclmac_apprenum_ = -1;
int
TclMac_IsAliasFile(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int aliases_available = 0, myerr;
long gestaltLong;
char pascal_name[256],
*ptr;
CInfoPBRec cpb;
struct stat statbuf;
#pragma unused (clientData)
if (argc != 2)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" filename\"", (char *) NULL);
return TCL_ERROR;
}
if (GestaltAvailable())
{
myerr = Gestalt(gestaltAliasMgrAttr, &gestaltLong);
if (myerr == noErr)
if ((gestaltLong & (1 << gestaltAliasMgrPresent)) != 0)
aliases_available = 1;
}
if ( ! aliases_available )
{
Tcl_AppendResult(interp, "0", NULL);
return TCL_OK;
}
if ( stat( argv[1], &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", argv[1], "\" ", NULL);
return TCL_ERROR;
}
if ( S_ISDIR(statbuf.st_mode) )
{
pascal_name[0] = '\0';
cpb.hFileInfo.ioDirID = statbuf.st_ino;
cpb.hFileInfo.ioFDirIndex = -1;
}
else
{
ptr = strrchr(argv[1], ':');
if (ptr != NULL)
strcpy(pascal_name, ptr);
else
strcpy(pascal_name, argv[1]);
c2pstr(pascal_name);
cpb.hFileInfo.ioDirID = statbuf.st_parid;
cpb.hFileInfo.ioFDirIndex = 0;
}
cpb.hFileInfo.ioCompletion = 0;
cpb.hFileInfo.ioNamePtr = (unsigned char *)pascal_name;
cpb.hFileInfo.ioVRefNum = statbuf.st_dev;
myerr = PBGetCatInfo( &cpb, (Boolean)0 );
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error getting file info for \"",
argv[1], "\" ", Tcl_MacGetError(interp, myerr), NULL);
return TCL_ERROR;
}
else
{
if ( (cpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x00008000) != 0 )
Tcl_SetResult(interp, "1", TCL_STATIC);
else
Tcl_SetResult(interp, "0", TCL_STATIC);
return TCL_OK;
}
}
int
TclMac_ResolveAlias(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
FSSpec fspec;
Boolean wasAliased, isFolder;
int aliases_available = 0, myerr;
long gestaltLong;
char pascal_name[256],
*ptr, savech;
struct stat statbuf;
#pragma unused (clientData)
if (argc != 2)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" filename\"", (char *) NULL);
return TCL_ERROR;
}
if (GestaltAvailable())
{
myerr = Gestalt(gestaltAliasMgrAttr, &gestaltLong);
if (myerr == noErr)
if ((gestaltLong & (1 << gestaltAliasMgrPresent)) != 0)
aliases_available = 1;
}
if ( ! aliases_available )
{
Tcl_SetResult(interp, argv[1], TCL_VOLATILE);
return TCL_OK;
}
if ( stat( argv[1], &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", argv[1], "\" ", NULL);
return TCL_ERROR;
}
ptr = strrchr(argv[1], ':');
if (ptr != NULL)
strcpy(pascal_name, ptr);
else
strcpy(pascal_name, argv[1]);
c2pstr(pascal_name);
BlockMove(pascal_name, fspec.name, pascal_name[0]+1);
fspec.parID = statbuf.st_parid;
fspec.vRefNum = statbuf.st_dev;
myerr = ResolveAliasFile(&fspec, (Boolean)1, &isFolder, &wasAliased);
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error resolving file \"", argv[1], "\" ",
Tcl_MacGetError(interp, myerr),
(char *) NULL);
return TCL_ERROR;
}
else if (wasAliased)
{
p2cstr(fspec.name);
Tcl_ResetResult(interp);
if (ptr != NULL)
{
savech = *(ptr+1);
*(ptr+1) = '\0';
Tcl_AppendResult(interp, argv[1], NULL);
*(ptr+1) = savech;
}
Tcl_AppendResult(interp, fspec.name, NULL);
return TCL_OK;
}
else
{
Tcl_SetResult(interp, argv[1], TCL_VOLATILE);
return TCL_OK;
}
}
#ifdef UNDONE
/* Feel free! You must be careful on the second filename. See Copy. */
int
TclMac_CreateAlias(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int aliases_available = 0, myerr;
long gestaltLong;
char pascal_name[256],
*ptr;
AliasHandle alias;
CInfoPBRec cpb;
struct stat statbuf;
#pragma unused (clientData)
if (argc != 3)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" filename aliasfilename\"", (char *) NULL);
return TCL_ERROR;
}
if (GestaltAvailable())
{
myerr = Gestalt(gestaltAliasMgrAttr, &gestaltLong);
if (myerr == noErr)
if ((gestaltLong & (1 << gestaltAliasMgrPresent)) != 0)
aliases_available = 1;
}
if ( ! aliases_available )
{
Tcl_AppendResult(interp, "could not create alias - ",
"aliases not supported on this Macintosh", NULL);
return TCL_ERROR;
}
if ( stat( argv[1], &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", argv[1], "\" ", NULL);
return TCL_ERROR;
}
if ( S_ISDIR(statbuf.st_mode) )
{
pascal_name[0] = '\0';
cpb.hFileInfo.ioDirID = statbuf.st_ino;
cpb.hFileInfo.ioFDirIndex = -1;
}
else
{
ptr = strrchr(argv[1], ':');
if (ptr != NULL)
strcpy(pascal_name, ptr);
else
strcpy(pascal_name, argv[1]);
c2pstr(pascal_name);
cpb.hFileInfo.ioDirID = statbuf.st_parid;
cpb.hFileInfo.ioFDirIndex = 0;
}
cpb.hFileInfo.ioCompletion = 0;
cpb.hFileInfo.ioNamePtr = (unsigned char *)pascal_name;
cpb.hFileInfo.ioVRefNum = statbuf.st_dev;
myerr = PBGetCatInfo( &cpb, (Boolean)0 );
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error getting file info for \"",
argv[1], "\" ", Tcl_MacGetError(interp, myerr), NULL);
return TCL_ERROR;
}
BlockMove(pascal_name, fspec.name, pascal_name[0]+1);
fspec.parID = statbuf.st_parid;
fspec.vRefNum = statbuf.st_dev;
myerr = NewAlias( (FSSpec *)0, &fspec, &alias );
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error creating alias record for \"",
argv[1], "\" ", Tcl_MacGetError(interp, myerr), NULL);
return TCL_ERROR;
}
/* UNDONE */
}
#endif
int
TclMac_GetFileInfo(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int myerr;
char buffer1[128];
char pascal_name[256], *ptr;
CInfoPBRec cpb;
DateTimeRec cdate, mdate;
struct stat statbuf;
#pragma unused (clientData, argc)
if ( argc != 2)
{
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " filename\"", NULL);
return TCL_ERROR;
}
if ( stat( argv[1], &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", argv[1], "\" ", NULL);
return TCL_ERROR;
}
if ( S_ISDIR(statbuf.st_mode) )
{
pascal_name[0] = '\0';
cpb.hFileInfo.ioDirID = statbuf.st_ino;
cpb.hFileInfo.ioFDirIndex = -1;
}
else
{
ptr = strrchr(argv[1], ':');
if (ptr != NULL)
strcpy(pascal_name, ptr);
else
strcpy(pascal_name, argv[1]);
c2pstr(pascal_name);
cpb.hFileInfo.ioDirID = statbuf.st_parid;
cpb.hFileInfo.ioFDirIndex = 0;
}
cpb.hFileInfo.ioCompletion = 0;
cpb.hFileInfo.ioNamePtr = (unsigned char *)pascal_name;
cpb.hFileInfo.ioVRefNum = statbuf.st_dev;
myerr = PBGetCatInfo( &cpb, (Boolean)0 );
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error getting file info for \"", argv[1], "\" ",
Tcl_MacGetError(interp, myerr), NULL);
return TCL_ERROR;
}
else {
Secs2Date(cpb.hFileInfo.ioFlCrDat, &cdate);
Secs2Date(cpb.hFileInfo.ioFlMdDat, &mdate);
sprintf(buffer1, "%4.4s", &cpb.hFileInfo.ioFlFndrInfo.fdCreator);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%4.4s", &cpb.hFileInfo.ioFlFndrInfo.fdType);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%c%c%c%c%c%c%c",
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&fHasBundle)!=0) ? 'B' : 'b' ),
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&fOnDesk)!=0) ? 'D' : 'd' ),
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&0x0100)!=0) ? 'I' : 'i' ),
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&0x8000)!=0) ? 'L' : 'l' ),
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&0x0080)!=0) ? 'M' : 'm' ),
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&0x1000)!=0) ? 'S' : 's' ),
( ((cpb.hFileInfo.ioFlFndrInfo.fdFlags&fInvisible)!=0) ? 'V' : 'v' )
);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%02d/%02d/%02d %02d:%02d:%02d",
cdate.month, cdate.day, cdate.year%100, cdate.hour, cdate.minute, cdate.second
);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%02d/%02d/%02d %02d:%02d:%02d",
mdate.month, mdate.day, mdate.year%100, mdate.hour, mdate.minute, mdate.second
);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%d %d",
cpb.hFileInfo.ioFlFndrInfo.fdLocation.h,
cpb.hFileInfo.ioFlFndrInfo.fdLocation.v
);
Tcl_AppendElement(interp, buffer1);
if ( S_ISDIR(statbuf.st_mode) )
{
sprintf(buffer1, "%ld", cpb.dirInfo.ioDrDirID);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%ld", cpb.dirInfo.ioDrNmFls);
Tcl_AppendElement(interp, buffer1);
}
else
{
sprintf(buffer1, "%ld", cpb.hFileInfo.ioFlLgLen);
Tcl_AppendElement(interp, buffer1);
sprintf(buffer1, "%ld", cpb.hFileInfo.ioFlRLgLen);
Tcl_AppendElement(interp, buffer1);
}
sprintf(buffer1, "%ld", cpb.hFileInfo.ioFlParID);
Tcl_AppendElement(interp, buffer1);
return TCL_OK;
}
}
TclMac_ParseDateString( date, dtstring )
DateTimeRec *date;
char *dtstring;
{
int result = 1,
date_args,
time_args,
yr, mo, dy,
hr, mn, sc;
long seconds;
char *ptr,
datestr[128],
timestr[128],
ampmstr[64];
date_args = sscanf(dtstring, "%s %s %s", &datestr, ×tr, &mstr);
if (date_args)
{
if ( sscanf(datestr, "%d/%d/%d", &mo, &dy, &yr) == 3 )
{
date->year = yr;
date->month = mo;
date->day = dy;
if (date_args > 1)
{
time_args = sscanf(timestr, "%d:%d:%d", &hr, &mn, &sc);
if (time_args == 2 || time_args < 3)
{
date->hour = hr;
date->minute = mn;
if (time_args > 2)
date->second = sc;
if (date_args > 2)
{
if (strcmp(ampmstr, "PM") == 0)
{
if (date->hour < 12)
date->hour += 12;
}
else if (strcmp(ampmstr, "AM") == 0)
{
if (date->hour == 12)
date->hour = 0;
}
else
result = 0;
}
}
else
result = 0;
}
}
else
result = 0;
}
else
result = 0;
return result;
}
int
TclMac_SetFileInfo(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
char *ptr;
int i, j, date_args;
Str255 pascal_name;
char datestr[128], timestr[128], ampmstr[64];
HParamBlockRec pb;
struct stat statbuf;
DateTimeRec date;
unsigned long seconds;
int yr, mo, dy, hr, mn, sc;
#pragma unused (clientData)
if ( argc < 3 )
{
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " filename settings...\"", NULL);
return TCL_ERROR;
}
if ( stat( argv[1], &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", argv[1], "\" ", NULL);
return TCL_ERROR;
}
ptr = strrchr(argv[1], ':');
if (ptr != NULL)
strcpy(pascal_name, ptr);
else
strcpy(pascal_name, argv[1]);
c2pstr(pascal_name);
pb.fileParam.ioCompletion = 0;
pb.fileParam.ioNamePtr = (unsigned char *)pascal_name;
pb.fileParam.ioDirID = statbuf.st_parid;
pb.fileParam.ioVRefNum = statbuf.st_dev;
pb.fileParam.ioFDirIndex = 0;
pb.fileParam.ioFVersNum = 0;
PBHGetFInfo(&pb, FALSE);
if (pb.fileParam.ioResult != noErr)
{
Tcl_AppendResult(interp, "error getting file info for \"", argv[1], "\" ",
Tcl_MacGetError(interp, pb.fileParam.ioResult),
(char *) NULL);
return TCL_ERROR;
}
else
{
for (i = 2 ; i < argc ; i += 2)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'a': /* attributes (lowercase = 0, uppercase = 1) [*] */
ptr = argv[i+1];
for (ptr = argv[i+1] ; *ptr ; ptr++)
{
switch (*ptr)
{
case 'L': case 'l': /* Locked / Not */
if (*ptr == 'L')
pb.fileParam.ioFlFndrInfo.fdFlags |= 0x8000;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~0x8000;
break;
case 'V': case 'v': /* Invisible / Visible */
if (*ptr == 'V')
pb.fileParam.ioFlFndrInfo.fdFlags |= fInvisible;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~fInvisible;
break;
case 'B': case 'b': /* Bundled / Not */
if (*ptr == 'B')
pb.fileParam.ioFlFndrInfo.fdFlags |= fHasBundle;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~fHasBundle;
break;
case 'S': case 's': /* System / Not */
if (*ptr == 'S')
pb.fileParam.ioFlFndrInfo.fdFlags |= 0x1000;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~0x1000;
break;
case 'I': case 'i': /* Inited / Not */
if (*ptr == 'I')
pb.fileParam.ioFlFndrInfo.fdFlags |= 0x0100;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~0x0100;
break;
case 'D': case 'd': /* 0x0001 Desktop / Not */
if (*ptr == 'D')
pb.fileParam.ioFlFndrInfo.fdFlags |= fOnDesk;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~fOnDesk;
break;
case 'M': case 'm': /* Sharable / Not */
if (*ptr == 'M')
pb.fileParam.ioFlFndrInfo.fdFlags |= 0x0080;
else
pb.fileParam.ioFlFndrInfo.fdFlags &= ~0x0080;
break;
}
}
break;
case 'c': /* file creator */
ptr = (char *) &pb.fileParam.ioFlFndrInfo.fdCreator;
for (j = 0 ; argv[i+1][j] ; j++)
*ptr++ = argv[i+1][j];
for ( ; j < 4 ; j++)
*ptr++ = ' ';
break;
case 'd': /* creation date (mm/dd/yy [hh:mm[:ss] [AM | PM]]) [*] */
if ( TclMac_ParseDateString( &date, argv[i+1] ) )
{
Date2Secs( &date, &seconds );
pb.fileParam.ioFlCrDat = seconds;
}
else
{
Tcl_AppendResult(interp, "bad creation date syntax \"",
argv[i+1], "\" ", NULL);
return TCL_ERROR;
}
break;
case 'm': /* modification date (mm/dd/yy [hh:mm[:ss] [AM | PM]]) [*] */
if ( TclMac_ParseDateString( &date, argv[i+1] ) )
{
Date2Secs( &date, &seconds );
pb.fileParam.ioFlMdDat = seconds;
}
else
{
Tcl_AppendResult(interp, "bad modification date syntax \"",
argv[i+1], "\" ", NULL);
return TCL_ERROR;
}
break;
case 't': /* file type */
ptr = (char *) &pb.fileParam.ioFlFndrInfo.fdType;
for (j = 0 ; argv[i+1][j] ; j++)
*ptr++ = argv[i+1][j];
for ( ; j < 4 ; j++)
*ptr++ = ' ';
break;
}
}
else
{
Tcl_AppendResult(interp, "\"", argv[0], "\" invalid option ",
argv[1], (char *) NULL);
return TCL_ERROR;
}
}
PBHSetFInfo(&pb, FALSE);
if (pb.fileParam.ioResult != noErr)
{
Tcl_AppendResult(interp, "error setting file info for \"", argv[1], "\" ",
Tcl_MacGetError(interp, pb.fileParam.ioResult),
(char *) NULL);
return TCL_ERROR;
}
}
return TCL_OK;
}
int
TclMac_CD(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int myerr;
WDPBRec wpb;
struct stat statbuf;
#pragma unused (clientData)
if (argc != 2)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" dirName\"", (char *) NULL);
return TCL_ERROR;
}
if ( stat( argv[1], &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", argv[1],
"\" ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
if ( ! S_ISDIR(statbuf.st_mode) )
{
Tcl_AppendResult(interp, "\"", argv[1], "\" not a directory", (char *) NULL);
return TCL_ERROR;
}
myerr = TclMac_CWDChgDir( statbuf.st_dev, statbuf.st_ino );
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error setting current directory \"",
argv[1], "\" ", Tcl_MacGetError(interp, myerr),
(char *) NULL);
return TCL_ERROR;
}
return TCL_OK;
}
int
TclMac_PWD(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int length;
char path[2048];
#pragma unused (clientData, argc, argv)
if ( argc != 1 )
{
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], "\"", NULL);
return TCL_ERROR;
}
TclMac_CWDPathName(path);
Tcl_SetResult(interp, path, TCL_VOLATILE);
return TCL_OK;
}
int
TclMac_MkDir(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int idx, dirArgc, result;
short vRefNum;
long dirID;
char **dirArgv, *dirName, *scanPtr, *ptr, pascal_name[256], savech;
HParamBlockRec pb;
struct stat statbuf;
Tcl_DString tildeBuf;
#pragma unused (clientData)
if ( argc != 2)
if ( argc != 3 || strcmp(argv [1], "-path") )
{
Tcl_AppendResult (interp, "wrong # args: ", argv [0],
" ?-path? dirlist", (char *) NULL);
return TCL_ERROR;
}
if ( Tcl_SplitList(interp, argv[argc - 1], &dirArgc, &dirArgv) != TCL_OK )
return TCL_ERROR;
Tcl_DStringInit (&tildeBuf);
/*
** Make all the directories, optionally making directories along the path.
*/
for ( idx = 0 ; idx < dirArgc ; idx++ )
{
dirName = Tcl_TildeSubst(interp, dirArgv[idx], &tildeBuf);
if (dirName == NULL)
{
Tcl_DStringFree (&tildeBuf);
ckfree ((char *) dirArgv);
return TCL_ERROR;
}
dirID = TclMac_CWDDirID();
vRefNum = TclMac_CWDVRefNum();
scanPtr = dirName;
if (*dirName != ':')
{
ptr = strchr(dirName, ':');
if (ptr != NULL)
{
savech = *(ptr+1);
*(ptr+1) = '\0';
if ( stat( dirName, &statbuf ) == 0 )
{
scanPtr = ptr;
dirID = statbuf.st_ino;
vRefNum = statbuf.st_dev;
}
else
{
Tcl_AppendResult (interp, "error locating volume \"", dirName,
"\" ", (char *) NULL);
*(ptr+1) = savech;
return TCL_ERROR;
}
*(ptr+1) = savech;
}
}
/*
** Make leading directories, if requested.
*/
result = 0; /* Start out ok, for dirs that are skipped */
for ( ; *scanPtr != '\0' ; )
{
if (*scanPtr == ':')
++scanPtr;
ptr = strchr(scanPtr, ':');
if ( ptr == NULL )
{
ptr = scanPtr + strlen(scanPtr);
}
savech = *ptr;
*ptr = '\0';
if ( stat(dirName, &statbuf) < 0 )
{
if ( argc == 3 || savech == '\0')
{
strcpy(pascal_name, scanPtr);
c2pstr(pascal_name);
pb.fileParam.ioCompletion = 0;
pb.fileParam.ioNamePtr = (unsigned char *)pascal_name;
pb.fileParam.ioVRefNum = vRefNum;
pb.fileParam.ioDirID = dirID;
result = PBDirCreate( (HParmBlkPtr)&pb, FALSE );
p2cstr(pascal_name);
if (result != noErr)
{
Tcl_AppendResult(interp, "error creating directory \"",
pascal_name, "\" ",
Tcl_MacGetError(interp, result),
(char *) NULL);
return TCL_ERROR;
}
else
{
if (stat(dirName, &statbuf) < 0)
{
Tcl_AppendResult(interp, "error locating directory \"",
dirName, "\" ", (char *) NULL);
return TCL_ERROR;
}
}
}
}
else
{
Tcl_AppendResult(interp, "error path \"", dirName,
"\" does not exist ", (char *) NULL);
return TCL_ERROR;
}
dirID = statbuf.st_ino;
vRefNum = statbuf.st_dev;
*ptr = savech;
scanPtr = ptr;
}
Tcl_DStringFree (&tildeBuf);
}
ckfree( (char *) dirArgv );
return TCL_OK;
}
int
TclMac_RmDir(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int idx, dirArgc, result;
char **dirArgv, *dirName;
HParamBlockRec pb;
struct stat statbuf;
Tcl_DString tildeBuf;
#pragma unused (clientData)
if ( argc != 2)
if ( argc != 3 || strcmp(argv [1], "-nocomplain") )
{
Tcl_AppendResult (interp, "wrong # args: ", argv [0],
" ?-nocomplain? dirlist", (char *) NULL);
return TCL_ERROR;
}
if ( Tcl_SplitList(interp, argv[argc - 1], &dirArgc, &dirArgv) != TCL_OK )
return TCL_ERROR;
Tcl_DStringInit (&tildeBuf);
for ( idx = 0 ; idx < dirArgc ; idx++ )
{
dirName = Tcl_TildeSubst(interp, dirArgv[idx], &tildeBuf);
if (dirName == NULL)
{
if (argc != 3)
{
Tcl_AppendResult(interp, "could not substitute for directory \"",
dirArgv[idx], "\" ", (char *) NULL);
Tcl_DStringFree (&tildeBuf);
return TCL_ERROR;
}
continue;
}
if ( stat( dirName, &statbuf ) < 0 )
{
if (argc != 3)
{
Tcl_AppendResult(interp, "error locating directory \"", dirArgv[idx], "\" ",
(char *) NULL);
Tcl_DStringFree (&tildeBuf);
return TCL_ERROR;
}
continue;
}
else if ( ! S_ISDIR(statbuf.st_mode) )
{
if (argc != 3)
{
Tcl_AppendResult(interp, "error \"", dirArgv[idx], "\" not a directory ",
(char *) NULL);
Tcl_DStringFree (&tildeBuf);
return TCL_ERROR;
}
continue;
}
pb.fileParam.ioCompletion = 0;
pb.fileParam.ioNamePtr = NULL;
pb.fileParam.ioVRefNum = statbuf.st_dev;
pb.fileParam.ioDirID = statbuf.st_ino;
result = PBHDelete( (HParmBlkPtr)&pb, FALSE );
if ( result != noErr && argc != 3 )
{
Tcl_AppendResult(interp, "error deleting \"", dirArgv[idx], "\" ",
Tcl_MacGetError(interp, result), (char *) NULL);
Tcl_DStringFree (&tildeBuf);
return TCL_ERROR;
}
Tcl_DStringFree (&tildeBuf);
}
ckfree ((char *) dirArgv);
return TCL_OK;
}
int
TclMac_Echo(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int i;
TCLPFI print_proc;
# pragma unused (interp, clientData)
print_proc = Tcl_GetPrintProcedure();
for (i = 1 ; i < argc ; ++i )
{
if (print_proc != NULL)
(*print_proc) (argv[i]);
else
fputs(argv[i], stdout);
if ( i < (argc - 1) )
if (print_proc != NULL)
(*print_proc) (" ");
else
fputs(" ", stdout);
}
if (print_proc != NULL)
(* print_proc)(SHELL_LINE_SEPER_STR);
else
fputs(SHELL_LINE_SEPER_STR, stdout);
return TCL_OK;
}
/*
** Expand arguments. '*argc' has only the arguments in it, not the original
** argc of the routine that called 'globArgs'. Likewise, 'argv' has been
** incremented.
*/
globArgs(Tcl_Interp *interp, int *argc, char ***argv)
{
int res, len;
char *list;
// Places the globbed args all into 'interp->result'.
res = Tcl_GlobCmd(0L, interp, *argc + 1, *argv - 1);
if (res != TCL_OK)
{
return FALSE;
}
len = strlen(interp->result);
list = (char *)calloc(len + 1, 1);
strcpy(list, interp->result);
Tcl_ResetResult(interp);
res = Tcl_SplitList(interp, list, argc, argv);
if (res != TCL_OK)
{
return FALSE;
}
free(list);
return TRUE;
}
TclMac_LS(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int line, i, j, k,
fFlag = FALSE,
lFlag = FALSE,
cFlag = FALSE,
hFlag = FALSE;
int lines, fieldLength, len = 0, maxLen = 0, perLine, result;
char theLine[512 + 2], *temp;
char c;
char **origArgv = argv;
struct stat statbuf;
#pragma unused (clientData)
// CHECK_FOR_WINS;
for (i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
break;
for ( j = 1 ; argv[i][j] ; ++j )
switch(argv[i][j])
{
case 'C':
cFlag = TRUE;
break;
case 'F':
fFlag = TRUE;
break;
case 'H':
hFlag = TRUE;
break;
case 'l':
lFlag = TRUE;
break;
default:
Tcl_AppendResult( interp, "error - unknown flag ",
"usage: ls -CFHl ?files? ", TCL_STATIC );
return TCL_ERROR;
}
}
argv += i;
argc -= i;
// No file specifications.
if (! argc)
{
argc = 1;
argv = origArgv;
strcpy(argv[0], "*");
}
if (! globArgs(interp, &argc, &argv))
{
Tcl_SetResult(interp, SHELL_LINE_SEPER_STR, TCL_STATIC);
return TCL_OK;
}
if (lFlag)
{
if (hFlag)
{
sprintf(theLine, "T %7s %7s %8s %8s %4s %4s %s",
"Size/ID", "RSize/N", "ModTime", "ModDate",
"CRTR", "TYPE", "Name" );
Tcl_AppendResult(interp, theLine, SHELL_LINE_SEPER_STR, NULL);
Tcl_AppendResult(interp,
"-------------------------------------------------------------",
SHELL_LINE_SEPER_STR, NULL);
}
for (i = 0; i < argc; i++)
{
char time[16];
char date[16];
int result;
result = stat( argv[i], &statbuf );
if (result != 0)
{
Tcl_AppendResult(interp, " error could not get info for \"", argv[i],
"\" ", Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
IUTimeString( statbuf.st_atime, FALSE, (unsigned char *)time );
IUDateString( statbuf.st_atime, shortDate, (unsigned char *)date );
p2cstr(time);
p2cstr(date);
if (S_ISDIR(statbuf.st_mode))
{
// Directory
sprintf(theLine, "D %7d %7d %8s %8s %-4.4s %-4.4s %s",
statbuf.st_ino, statbuf.st_nlink, time, date,
&statbuf.fdCreator, &statbuf.fdType, argv[i] );
}
else
{
// FILE
sprintf( theLine, "F %7d %7d %8s %8s %-4.4s %-4.4s %s",
statbuf.st_size, statbuf.st_rsize, time, date,
&statbuf.fdCreator, &statbuf.fdType, argv[i] );
}
Tcl_AppendResult(interp, theLine, SHELL_LINE_SEPER_STR, NULL);
}
if (interp->result != NULL && *(interp->result) != '\0')
{
int slen = strlen(interp->result);
if (interp->result[slen - 1] == SHELL_LINE_SEPER_CHAR)
interp->result[slen - 1] = '\0';
}
}
else
{
// Ordinary case.
for (i = 0; i < argc; i++)
{
/* UNDONE - Alias resolution handling */
len = strlen(argv[i]);
if (len > maxLen) maxLen = len;
}
fieldLength = maxLen + 3;
if (! cFlag)
perLine = 1;
else
perLine = 80 / fieldLength;
lines = ((argc - 1) / perLine) + 1;
theLine[sizeof(theLine) - 2] = SHELL_LINE_SEPER_CHAR;
theLine[sizeof(theLine) - 1] = 0;
for ( line = 0 ; line < lines ; ++line )
{
memset(theLine, ' ', sizeof(theLine) - 2);
for ( k = 0 ; k < perLine ; ++k )
{
int num = line + k * lines;
if (num >= argc) continue;
temp = theLine + (k * fieldLength);
memset(temp, ' ', fieldLength);
len = strlen(argv[num]);
strncpy(temp, argv[num], len);
if (fFlag)
{
result = stat( argv[num], &statbuf );
if (result != 0)
{
Tcl_AppendResult(interp, " error could not get info for \"", argv[num],
"\" ", Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
if (S_ISDIR(statbuf.st_mode))
{
if (temp[len-1] != ':')
c = ':';
}
else if ( statbuf.fdType == (long)'APPL')
{
c = '•';
}
else c = ' ';
temp[len] = c;
}
}
if (line == (lines - 1))
{
theLine[fieldLength * perLine] = 0;
}
theLine[80] = SHELL_LINE_SEPER_CHAR;
theLine[81] = 0;
Tcl_AppendResult(interp, theLine, NULL);
}
}
ckfree((char *) argv);
return TCL_OK;
}
int
TclMac_CTime(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
char *ptr;
unsigned long seconds;
#pragma unused (clientData)
if (argc != 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" time\"", (char *) NULL);
return TCL_ERROR;
}
else
{
seconds = atol(argv[1]);
ptr = ctime(&seconds);
ptr[strlen(ptr)-1] = '\0'; /* Drop \n */
Tcl_SetResult(interp, ptr, TCL_VOLATILE);
return TCL_OK;
}
}
int
TclMac_DateTime(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
char datestr[64], timestr[64];
unsigned long now;
#pragma unused (clientData)
if (argc < 2 || argc > 3)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" time ?format?\" where format is \"long, short, or abbrev\"", (char *) NULL);
return TCL_ERROR;
}
else
{
if (sscanf(argv[1], "%lu", &now) != 1)
{
Tcl_AppendResult(interp, "invalid time \"", argv[1], "\"", (char *) NULL);
return TCL_ERROR;
}
else
{
IUDateString(now, ( argc == 2 ? shortDate :
( argv[2][0] == 's' ? shortDate :
(argv[2][0] == 'l' ? longDate : abbrevDate) ) ),
(unsigned char *)datestr);
IUTimeString(now, TRUE, (unsigned char *)timestr);
p2cstr(datestr);
p2cstr(timestr);
Tcl_AppendElement(interp, datestr);
Tcl_AppendElement(interp, timestr);
return TCL_OK;
}
}
}
int
TclMac_Ticks(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
char tickstr[64];
#pragma unused (clientData, argv)
if (argc != 1)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], "\"", (char *) NULL);
return TCL_ERROR;
}
else
{
sprintf(tickstr, "%lu", TickCount());
Tcl_SetResult(interp, tickstr, TCL_VOLATILE);
return TCL_OK;
}
}
int
TclMac_CvtTime(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
unsigned long now, myseconds;
char nowstr[64];
#pragma unused (clientData, argv)
if ( argc != 3 ||
( strcmp("-mtu", argv[1]) && strcmp("-utm", argv[1])) )
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
"\" [-mtu|-utm] seconds", (char *) NULL);
return TCL_ERROR;
}
else
{
if ( sscanf(argv[2], "%ld", &myseconds) != 1 )
{
Tcl_AppendResult(interp, "invalid seconds parameter \"", argv[2],
"\"", (char *) NULL);
return TCL_ERROR;
}
if ( strcmp(argv[1], "-mtu") == 0 )
{
myseconds -= TIMEDIFF;
}
else if ( strcmp(argv[1], "-utm") == 0 )
{
myseconds += TIMEDIFF;
}
sprintf( nowstr, "%lu", myseconds );
Tcl_SetResult(interp, nowstr, TCL_VOLATILE);
return TCL_OK;
}
}
int
TclMac_Now(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
unsigned long now;
char nowstr[64];
#pragma unused (clientData, argv)
if ( ! ( argc == 1 || (argc == 2 && strcmp(argv[1], "-unix")) ) )
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
"\" ?-unix?", (char *) NULL);
return TCL_ERROR;
}
else
{
GetDateTime(&now);
sprintf( nowstr, "%lu", (argc == 1 ? now : (now - TIMEDIFF)) );
Tcl_SetResult(interp, nowstr, TCL_VOLATILE);
return TCL_OK;
}
}
int
TclMac_RM(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int myerr;
short vrefnum;
long dirid;
char *ptr1;
Str32 pascal_name;
int idx, myArgc, result;
int nocomplain = 0;
char **myArgv, *fileName;
HParamBlockRec pb;
struct stat statbuf;
Tcl_DString tildeBuf;
#pragma unused (clientData)
if ( argc != 2)
if ( argc != 3 || ( strcmp(argv [1], "-f")
&& strcmp(argv [1], "-nocomplain") ) )
{
Tcl_AppendResult (interp, "wrong # args: ", argv [0],
" ?-nocomplain? filelist", (char *) NULL);
return TCL_ERROR;
}
if (argc == 3)
nocomplain = 1;
if ( Tcl_SplitList(interp, argv[argc - 1], &myArgc, &myArgv) != TCL_OK )
return TCL_ERROR;
Tcl_DStringInit (&tildeBuf);
for ( idx = 0 ; idx < myArgc ; idx++ )
{
fileName = Tcl_TildeSubst(interp, myArgv[idx], &tildeBuf);
if (fileName == NULL)
{
if (!nocomplain)
{
Tcl_AppendResult(interp, "could not substitute for directory \"",
myArgv[idx], "\" ", (char *) NULL);
Tcl_DStringFree (&tildeBuf);
return TCL_ERROR;
}
continue;
}
if ( stat( fileName, &statbuf ) != 0 )
{
if (!nocomplain)
{
Tcl_AppendResult(interp, "could not locate file \"", fileName,
"\" ", Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
continue;
}
dirid = statbuf.st_parid;
vrefnum = statbuf.st_dev;
ptr1 = strrchr(fileName, ':');
if (ptr1 == NULL)
ptr1 = fileName;
else
++ptr1;
strncpy( (char *)pascal_name, ptr1, sizeof(pascal_name)-1 );
pascal_name[sizeof(pascal_name)-1] = '\0';
c2pstr((char *)pascal_name);
pb.fileParam.ioCompletion = 0;
pb.fileParam.ioNamePtr = pascal_name;
pb.fileParam.ioVRefNum = vrefnum;
pb.fileParam.ioDirID = dirid;
myerr = PBHDelete(&pb, FALSE);
if (myerr != noErr && !nocomplain)
{
Tcl_AppendResult(interp, "\"", argv[0], "\" ", "error deleting \"",
argv[1], "\" ", Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
}
return TCL_OK;
}
int
TclMac_MoveFile(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int myerr,
force = 0;
short from_vrefnum,
to_vrefnum;
long from_dirid,
to_dirid;
char *ptr1, *ptr2,
*oldname, *newname,
savech;
char pascal_name[64],
from_name[64],
to_name[64];
HParamBlockRec pb;
CMovePBRec mpb;
struct stat statbuf;
#pragma unused (clientData)
if (argc < 3 || argc > 4)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" oldName newName ?force?\"", (char *) NULL);
return TCL_ERROR;
}
if (argc == 4)
{
if (strcmp(argv[3], "force"))
{
Tcl_AppendResult(interp, "wrong parameter \"", argv[3], "\" : should be \"", argv[0],
" oldName newName ?force?\"", (char *) NULL);
return TCL_ERROR;
}
force = 1;
}
oldname = argv[1];
newname = argv[2];
if ( stat( oldname, &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", oldname, "\" ", NULL);
return TCL_ERROR;
}
from_dirid = statbuf.st_parid;
from_vrefnum = statbuf.st_dev;
ptr1 = strrchr(oldname, ':');
ptr2 = strrchr(newname, ':');
if (ptr1 != NULL)
strcpy(from_name, ptr1 + 1);
else
strcpy(from_name, oldname);
if (ptr2 != NULL)
{
savech = *(ptr2+1);
*(ptr2+1) = '\0';
tcl_path_to_dir(newname, &to_vrefnum, &to_dirid);
*(ptr2+1) = savech;
strcpy(to_name, ptr2 + 1);
}
else
{
strcpy(to_name, newname);
to_dirid = TclMac_CWDDirID();
to_vrefnum = TclMac_CWDVRefNum();
}
if ( from_vrefnum != to_vrefnum )
{
if (TclMac_CopyFile(clientData, interp, argc, argv) == TCL_ERROR)
return TCL_ERROR;
else
return TclMac_RM(clientData, interp, --argc, argv);
}
if ( from_dirid != to_dirid )
{
strcpy(pascal_name, from_name);
c2pstr(pascal_name);
retry_move:
mpb.ioCompletion = 0;
mpb.ioNamePtr = (unsigned char *)pascal_name;
mpb.ioVRefNum = from_vrefnum;
mpb.ioNewName = "\p";
mpb.ioNewDirID = to_dirid;
mpb.ioDirID = from_dirid;
myerr = PBCatMove(&mpb, FALSE);
if (myerr != noErr)
{
if (force && myerr == dupFNErr)
{
pb.fileParam.ioCompletion = 0;
pb.fileParam.ioNamePtr = (unsigned char *)pascal_name;
pb.fileParam.ioVRefNum = from_vrefnum;
pb.fileParam.ioFVersNum = 0;
pb.fileParam.ioDirID = to_dirid;
myerr = PBHDelete(&pb, FALSE);
if (myerr == noErr)
goto retry_move;
}
Tcl_AppendResult(interp, "\"", argv[0], "\" error moving file ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
}
if (strcmp(from_name, to_name) != 0)
{
c2pstr(from_name);
c2pstr(to_name);
retry_rename:
pb.ioParam.ioCompletion = 0;
pb.ioParam.ioNamePtr = (unsigned char *)from_name;
pb.ioParam.ioVRefNum = from_vrefnum;
pb.ioParam.ioMisc = to_name;
pb.ioParam.ioVersNum = 0;
pb.fileParam.ioDirID = to_dirid;
myerr = PBHRename(&pb, FALSE);
if (myerr != noErr)
{
if (force && myerr == dupFNErr)
{
pb.fileParam.ioCompletion = 0;
pb.fileParam.ioNamePtr = (unsigned char *)to_name;
pb.fileParam.ioVRefNum = from_vrefnum;
pb.fileParam.ioFVersNum = 0;
pb.fileParam.ioDirID = to_dirid;
myerr = PBHDelete(&pb, FALSE);
if (myerr == noErr)
goto retry_rename;
}
Tcl_AppendResult(interp, "\"", argv[0], "\" error renaming file ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
}
return TCL_OK;
}
int
TclMac_CopyFile(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
int myerr, eoferr, need_move = 0, need_rename = 0, force = 0;
short from_vrefnum, to_vrefnum, inerr, outerr;
long from_dirid, to_dirid;
char *ptr1, *ptr2, savech, *oldname, *newname;
char from_name[64], to_name[64];
struct stat statbuf;
HParamBlockRec inparm, outparm;
#pragma unused (clientData)
if (argc < 3 || argc > 4) {
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" fromName toName ?force?\"", (char *) NULL);
return TCL_ERROR;
}
if (argc == 4)
{
if (strcmp(argv[3], "force"))
{
Tcl_AppendResult(interp, "wrong parameter \"", argv[3], "\" : should be \"", argv[0],
" oldName newName ?force?\"", (char *) NULL);
return TCL_ERROR;
}
force = 1;
}
oldname = argv[1];
newname = argv[2];
if ( stat( oldname, &statbuf ) != 0)
{
Tcl_AppendResult(interp, "could not locate file \"", oldname, "\" ", NULL);
return TCL_ERROR;
}
from_dirid = statbuf.st_parid;
from_vrefnum = statbuf.st_dev;
ptr1 = strrchr(oldname, ':');
ptr2 = strrchr(newname, ':');
if (ptr1 != NULL)
strcpy(from_name, ptr1 + 1);
else
strcpy(from_name, oldname);
if (ptr2 != NULL)
{
savech = *(ptr2+1);
*(ptr2+1) = '\0';
tcl_path_to_dir(newname, &to_vrefnum, &to_dirid);
*(ptr2+1) = savech;
strcpy(to_name, ptr2 + 1);
}
else
{
strcpy(to_name, newname);
to_dirid = TclMac_CWDDirID();
to_vrefnum = TclMac_CWDVRefNum();
}
c2pstr(from_name);
c2pstr(to_name);
inparm.ioParam.ioCompletion = 0;
inparm.ioParam.ioNamePtr = (unsigned char *)from_name;
inparm.ioParam.ioVRefNum = from_vrefnum;
inparm.ioParam.ioVersNum = 0;
inparm.ioParam.ioPermssn = fsRdPerm;
inparm.ioParam.ioMisc = NULL;
inparm.fileParam.ioDirID = from_dirid;
inerr = PBHOpen(&inparm, FALSE);
if (inerr != noErr)
{
p2cstr(from_name);
Tcl_AppendResult(interp, "error opening DATA fork \"", from_name, "\" ",
Tcl_MacGetError(interp, inerr), (char *) NULL);
return TCL_ERROR;
}
outparm.ioParam.ioCompletion = 0;
outparm.ioParam.ioNamePtr = (unsigned char *)to_name;
outparm.ioParam.ioVRefNum = to_vrefnum;
outparm.ioParam.ioVersNum = 0;
outparm.ioParam.ioPermssn = fsWrPerm;
outparm.ioParam.ioMisc = NULL;
outparm.fileParam.ioDirID = to_dirid;
outerr = PBHCreate(&outparm, false);
if ( (outerr != noErr && outerr != dupFNErr) ||
(outerr == dupFNErr && ! force) )
{
PBClose((ParmBlkPtr)&inparm, false);
p2cstr(to_name);
Tcl_AppendResult(interp, "error creating DATA fork \"", to_name, "\" ",
Tcl_MacGetError(interp, outerr), (char *) NULL);
return TCL_ERROR;
}
outerr = PBHOpen(&outparm, false);
if (outerr != noErr)
{
PBClose((ParmBlkPtr)&inparm, false);
p2cstr(to_name);
Tcl_AppendResult(interp, "error opening DATA fork \"", to_name, "\" ",
Tcl_MacGetError(interp, outerr), (char *) NULL);
return TCL_ERROR;
}
myerr = TclMac_CopyFork(&inparm, &outparm);
PBGetEOF((ParmBlkPtr)&inparm, FALSE);
outparm.ioParam.ioMisc = inparm.ioParam.ioMisc;
eoferr = PBSetEOF((ParmBlkPtr)&outparm, FALSE);
PBClose((ParmBlkPtr)&inparm, FALSE);
PBClose((ParmBlkPtr)&outparm, FALSE);
FlushVol(NULL, to_vrefnum);
if (myerr != noErr)
{
p2cstr(to_name);
p2cstr(from_name);
Tcl_AppendResult(interp, "error copying DATA fork \"",
from_name, "\" to \"", to_name, "\" ", (char *) NULL);
return TCL_ERROR;
}
if (eoferr != noErr)
{
Tcl_AppendResult(interp, "error setting DATA fork EOF ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
inparm.ioParam.ioCompletion = 0;
inparm.ioParam.ioNamePtr = (unsigned char *)from_name;
inparm.ioParam.ioVRefNum = from_vrefnum;
inparm.ioParam.ioVersNum = 0;
inparm.ioParam.ioPermssn = fsRdPerm;
inparm.ioParam.ioMisc = NULL;
inparm.fileParam.ioDirID = from_dirid;
myerr = PBHOpenRF(&inparm, FALSE);
if (myerr != noErr && myerr != eofErr && myerr != fnfErr)
{
p2cstr(from_name);
Tcl_AppendResult(interp, "error opening RSRC fork \"", from_name, "\" ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
else if (myerr == noErr)
{
outparm.ioParam.ioCompletion = 0;
outparm.ioParam.ioNamePtr = (unsigned char *)to_name;
outparm.ioParam.ioVRefNum = to_vrefnum;
outparm.ioParam.ioVersNum = 0;
outparm.ioParam.ioPermssn = fsWrPerm;
outparm.ioParam.ioMisc = NULL;
outparm.fileParam.ioDirID = to_dirid;
myerr = PBHOpenRF(&outparm, false);
if (myerr != noErr)
{
PBClose((ParmBlkPtr)&inparm, FALSE);
p2cstr(to_name);
Tcl_AppendResult(interp, "error opening RSRC fork \"", to_name, "\" ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
myerr = TclMac_CopyFork(&inparm, &outparm);
PBGetEOF((ParmBlkPtr)&inparm, FALSE);
outparm.ioParam.ioMisc = inparm.ioParam.ioMisc;
eoferr = PBSetEOF((ParmBlkPtr)&outparm, FALSE);
PBClose((ParmBlkPtr)&inparm, FALSE);
PBClose((ParmBlkPtr)&outparm, FALSE);
if (myerr != noErr)
{
p2cstr(to_name);
p2cstr(from_name);
Tcl_AppendResult(interp, "error copying RSRC \"",
from_name, "\" to \"", to_name, "\" ", (char *) NULL);
return TCL_ERROR;
}
if (eoferr != noErr)
{
Tcl_AppendResult(interp, "error setting RSRC EOF ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
}
FlushVol(NULL, to_vrefnum);
inparm.fileParam.ioCompletion = 0;
inparm.fileParam.ioNamePtr = (unsigned char *)from_name;
inparm.fileParam.ioVRefNum = from_vrefnum;
inparm.fileParam.ioFVersNum = 0;
inparm.fileParam.ioDirID = from_dirid;
inparm.fileParam.ioFDirIndex = 0;
myerr = PBHGetFInfo(&inparm, FALSE);
if (myerr == noErr)
{
outparm.fileParam.ioCompletion = 0;
outparm.fileParam.ioNamePtr = (unsigned char *)to_name;
outparm.fileParam.ioVRefNum = to_vrefnum;
outparm.fileParam.ioFVersNum = 0;
outparm.fileParam.ioDirID = to_dirid;
outparm.fileParam.ioFDirIndex = 0;
outparm.fileParam.ioFlFndrInfo = inparm.fileParam.ioFlFndrInfo;
outparm.fileParam.ioFlFndrInfo.fdLocation.h += 16;
outparm.fileParam.ioFlFndrInfo.fdLocation.v += 16;
GetDateTime(&outparm.fileParam.ioFlCrDat);
outparm.fileParam.ioFlMdDat = outparm.fileParam.ioFlCrDat;
myerr = PBHSetFInfo(&outparm, FALSE);
if (myerr != noErr)
{
Tcl_AppendResult(interp, "error setting Finder info ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
}
else
{
Tcl_AppendResult(interp, "error getting Finder info ",
Tcl_MacGetError(interp, myerr), (char *) NULL);
return TCL_ERROR;
}
FlushVol(NULL, to_vrefnum);
return TCL_OK;
}
int
TclMac_CopyFork(inparm, outparm)
HParamBlockRec *inparm;
HParamBlockRec *outparm;
{
short done, myerr;
ParamBlockRec ipb, opb;
char mybuffer[1024];
for (done=false; ! done; )
{
ipb.ioParam.ioCompletion = 0;
ipb.ioParam.ioRefNum = inparm->ioParam.ioRefNum;
ipb.ioParam.ioReqCount = (long) sizeof(mybuffer);
ipb.ioParam.ioBuffer = mybuffer;
ipb.ioParam.ioPosMode = fsAtMark;
ipb.ioParam.ioPosOffset = 0;
myerr = PBRead( &ipb, (Boolean)0 );
if (myerr == eofErr)
done = true;
else if (myerr != noErr)
return myerr;
if (ipb.ioParam.ioActCount > 0)
{
opb.ioParam.ioCompletion = 0;
opb.ioParam.ioRefNum = outparm->ioParam.ioRefNum;
opb.ioParam.ioReqCount = ipb.ioParam.ioActCount;
opb.ioParam.ioBuffer = mybuffer;
opb.ioParam.ioPosMode = fsAtMark;
opb.ioParam.ioPosOffset = 0;
myerr = PBWrite( &opb, (Boolean)0 );
if (myerr != noErr)
return myerr;
if ( ipb.ioParam.ioActCount != opb.ioParam.ioActCount )
done = true;
}
}
return noErr;
}
int
volname_to_vref(volname, vrefnum)
char *volname;
short *vrefnum;
{
int myerr;
char pascal_name[32];
HParamBlockRec pb;
strncpy(pascal_name, volname, 28);
pascal_name[28] = '\0';
c2pstr(pascal_name);
if (pascal_name[ pascal_name[0] ] != ':')
{
pascal_name[ ++pascal_name[0] ] = ':';
}
pb.volumeParam.ioCompletion = 0;
pb.volumeParam.ioVRefNum = 0;
pb.volumeParam.ioNamePtr = (unsigned char *)pascal_name;
pb.volumeParam.ioVolIndex = -1;
myerr = PBHGetVInfo(&pb, FALSE);
if (myerr == noErr)
{
*vrefnum = pb.volumeParam.ioVRefNum;
}
return myerr;
}
tcl_path_to_dir(path, vRefNum, dirID)
char *path;
short *vRefNum;
long *dirID;
{
short vref;
int myerr, result = noErr;
long dirid;
char *pathptr, *ptr, savech;
CInfoPBRec cpb;
vref = TclMac_CWDVRefNum();
dirid = TclMac_CWDDirID();
ptr = strchr(path, ':');
if (ptr == NULL)
{
/* No path, just a filename... */
*vRefNum = vref;
*dirID = dirid;
return noErr;
}
if (*path == ':')
{
/* RELATIVE */
pathptr = path + 1;
if (*pathptr == '\0')
{
*vRefNum = vref;
*dirID = dirid;
return noErr;
}
}
else
{
/* ABSOLUTE */
++ptr;
savech = *ptr;
*ptr = '\0';
dirid = 2; /* root level */
myerr = volname_to_vref(path, &vref);
if (myerr != noErr)
return myerr;
*ptr = savech;
pathptr = ptr;
}
for ( ; ; )
{
if (*ptr == '\0')
break;
ptr = strchr(pathptr, ':');
if (ptr == NULL)
break;
cpb.hFileInfo.ioCompletion = 0;
cpb.hFileInfo.ioNamePtr = (unsigned char *)pathptr;
cpb.hFileInfo.ioVRefNum = vref;
cpb.hFileInfo.ioFDirIndex = 0;
cpb.hFileInfo.ioDirID = dirid;
savech = *ptr;
*ptr = '\0';
c2pstr(pathptr);
myerr = PBGetCatInfo(&cpb, (Boolean)0);
p2cstr(pathptr);
*ptr = savech;
pathptr = ++ptr;
if (myerr != noErr)
{
result = myerr;
break;
}
else
{
if ((cpb.hFileInfo.ioFlAttrib & ioDirMask) == 0)
{
/* UNDONE -- aliases? */
break;
}
else
{
dirid = cpb.hFileInfo.ioDirID;
}
}
}
*vRefNum = vref;
*dirID = dirid;
return result;
}
/*
*-----------------------------------------------------------------------------
*
* Mac_EvalResource --
* Used to extend the source command. Sources Tcl code from a Text resource.
* Currently only sources the resouce by name file ID may be supported
* at a later date.
*
* Side Effects:
* Depends on the Tcl code in the resource.
*
* Results:
* Returns a Tcl result.
*
*-----------------------------------------------------------------------------
*/
int
Mac_EvalResource(interp, resourceName, resourceNumber, resourceFile)
Tcl_Interp *interp; /* Interpreter in which to process file. */
char *resourceName; /* Name of TEXT resource to source, NULL if number should be used. */
int resourceNumber; /* Resource id of source. */
char *resourceFile; /* Name of file to process. NULL if application resource. */
{
Handle sourceText;
short saveref, fileRef = -1;
char idStr[64], *ptr;
char pascal_name[256];
int result, size;
struct stat statbuf;
saveref = CurResFile();
if (resourceFile != NULL)
{
if ( stat(resourceFile, &statbuf ) < 0 )
{
Tcl_AppendResult(interp, "could not locate resource file \"",
resourceFile, "\" ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
ptr = strrchr( resourceFile, ':');
if (ptr != NULL)
strcpy(pascal_name, ptr+1);
else
strcpy(pascal_name, resourceFile);
c2pstr(pascal_name);
fileRef = HOpenResFile( statbuf.st_dev, statbuf.st_parid,
(unsigned char *)pascal_name, fsRdPerm);
if (fileRef == -1)
{
Tcl_AppendResult(interp, "could not open resource file \"",
resourceFile, "\" ",
Tcl_MacGetError(interp, ResError()), NULL);
return TCL_ERROR;
}
UseResFile(fileRef);
}
else if (_tclmac_apprenum_ != -1)
{
UseResFile(_tclmac_apprenum_);
}
if (resourceName != NULL)
{
strcpy(pascal_name, resourceName);
c2pstr(pascal_name);
sourceText = GetNamedResource( (ResType)'TEXT', (unsigned char *)pascal_name );
}
else
{
sourceText = GetResource( (ResType)'TEXT', (short)resourceNumber );
}
if ( sourceText == NULL )
{
sprintf(idStr, "ID=%d", resourceNumber );
Tcl_AppendResult(interp, "The resource \"",
(resourceName != NULL ? resourceName : idStr),
"\" could not be loaded from ",
(resourceFile != NULL ? resourceFile : "application"),
".", NULL);
return TCL_ERROR;
}
HLock(sourceText);
size = SizeResource(sourceText);
(*sourceText)[size - 1] = '\0'; /* Terminate it if resource didn't */
result = Tcl_Eval( interp, *sourceText );
if (result == TCL_RETURN)
{
result = TCL_OK;
}
else if (result == TCL_ERROR)
{
sprintf(idStr, "ID=%d", resourceNumber);
Tcl_AppendResult(interp, " (rsrc \"",
(resourceName == NULL ? idStr : resourceName),
"\" ", NULL);
sprintf(idStr, "%d", interp->errorLine);
Tcl_AppendResult(interp, " line ", idStr, ") ", NULL);
}
HUnlock(sourceText);
ReleaseResource( sourceText );
if (fileRef != -1)
CloseResFile(fileRef);
UseResFile(saveref);
return result;
}
/*
*----------------------------------------------------------------------
*
* Mac_SourceCmd --
*
* This procedure is invoked to process the "source" Tcl command.
* See the user documentation for details on what it does. In addition,
* it supports sourceing from the resource fork of type 'TEXT'.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
*
*----------------------------------------------------------------------
*/
int
Mac_SourceCmd(clientData, interp, argc, argv)
ClientData clientData; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
char **argv; /* Argument strings. */
{
int rsrcid = 0, i;
char *rsrcname = NULL;
char *rsrcfile = NULL;
#pragma unused (clientData)
if (argc < 2)
{
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" fileName | ?-rsrcfile path? [-rsrcname name | -rsrcid id]\"",
(char *) NULL);
return TCL_ERROR;
}
else if (argc == 2)
{
return Tcl_EvalFile(interp, argv[1]);
}
else
{
for ( i = 1 ; i < argc ; ++i )
{
if (strcmp(argv[i], "-rsrcname") == 0)
{
rsrcname = argv[i + 1];
++i;
}
else if (strcmp(argv[i], "-rsrcid") == 0)
{
rsrcid = atoi(argv[i + 1]);
++i;
}
else if (strcmp(argv[i], "-rsrcfile") == 0)
{
rsrcfile = argv[i + 1];
++i;
}
else
{
Tcl_AppendResult(interp, "bad argument: should be \"", argv[0],
" fileName | [-rsrcname name | -rsrcid id] ?-rsrcfile path?\"",
(char *) NULL);
return TCL_ERROR;
}
}
return Mac_EvalResource( interp, rsrcname, rsrcid, rsrcfile);
}
}
int
Mac_BeepCmd(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char *argv[];
{
Handle sound;
Str255 sndName;
#pragma unused (clientData)
if ( argc == 1 )
{
SysBeep(1);
return TCL_OK;
}
else if ( argc == 2 )
{
if ( ! strcmp(argv[1], "-list") )
{
int count, i;
short id;
Str255 theName;
ResType theType;
Tcl_ResetResult( interp );
count = CountResources( 'snd ' );
for ( i = 1 ; i <= count ; i++ )
{
sound = GetIndResource( 'snd ', i );
if ( sound != NULL )
{
GetResInfo( sound, &id, &theType, theName );
if ( theName[0] == 0 ) continue;
theName[theName[0]+1] = '\0';
Tcl_AppendElement( interp, (char *) theName + 1 );
}
}
return TCL_OK;
}
else
{
strcpy( (char *) sndName + 1, argv[1] );
sndName[0] = strlen(argv[1]);
sound = GetNamedResource( 'snd ', sndName );
if ( sound != NULL )
{
SndPlay( NULL, sound, FALSE );
return TCL_OK;
}
else {
Tcl_ResetResult( interp );
Tcl_AppendResult( interp, "Error: \"", argv[1],
"\" is not a valid beep sound. (Try beep -list)", NULL );
return TCL_ERROR;
}
}
}
else
{
return TCL_ERROR;
}
}
#define CurrentSysEnvVersion 1
get_system_version(str)
char *str;
{
int myerr = gestaltUnknownErr;
long gestaltLong;
SysEnvRec sysEnviron;
if (GestaltAvailable())
{
myerr = Gestalt(gestaltSystemVersion, &gestaltLong);
if (myerr == noErr)
{
sprintf( str, "%d.%02d",
( (gestaltLong >> 8) & 0x00FF ),
( (gestaltLong) & 0x00FF ) );
}
}
if (myerr != noErr)
{
memset(&sysEnviron, 0, sizeof(SysEnvRec));
if (SysEnvirons(CurrentSysEnvVersion, &sysEnviron) != noErr)
{
strcpy( str, "0.0" );
}
else
{
sprintf( str, "%d.%02d",
( (sysEnviron.systemVersion >> 8) & 0x00FF ),
( (sysEnviron.systemVersion) & 0x00FF ) );
}
}
}
get_machine_name(str)
char *str;
{
int myerr = gestaltUnknownErr;
short index = 0;
long gestaltLong;
SysEnvRec sysEnviron;
if (GestaltAvailable())
{
myerr = Gestalt(gestaltSystemVersion, &gestaltLong);
if (myerr == noErr)
index = gestaltLong;
}
if (myerr != noErr)
{
memset(&sysEnviron, 0, sizeof(SysEnvRec));
if (SysEnvirons(CurrentSysEnvVersion, &sysEnviron) == noErr)
index = sysEnviron.machineType;
}
*str = '\0';
if (index > 0)
{
GetIndString((unsigned char *)str, kMachineNameStrID, index);
p2cstr(str);
}
if (*str == '\0')
strcpy(str, "unknown");
}
get_user_name(user_name)
char *user_name;
{
short refnum;
Handle hdl;
refnum = CurResFile();
UseResFile(0);
hdl = GetResource( (ResType)'STR ', -16096 );
UseResFile(refnum);
if (hdl)
{
LoadResource(hdl);
HLock(hdl);
sprintf( user_name, "%.*s",
( **hdl > 31 ? 31 : **hdl ), (*hdl) + 1 );
HUnlock(hdl);
}
else
{
strcpy(user_name, "anonymous");
}
}
char *
tcl_check_path_termination( char *path )
{
int length;
length = strlen(path);
if ( path[ length-1 ] == ':' )
path[ length-1 ] = '\0';
return path;
}
GetRefnumPathName(pathname, refnum)
char *pathname;
int refnum;
{
int result;
FCBPBRec pb;
Str32 name;
pb.ioCompletion = 0;
pb.ioVRefNum = 0;
pb.ioRefNum = (short)refnum;
pb.ioNamePtr = (unsigned char *)name;
pb.ioFCBIndx = 0;
result = PBGetFCBInfo( &pb, FALSE );
if (result == noErr)
{
dirpathname(pathname, pb.ioVRefNum, pb.ioFCBParID);
}
return result;
}
GetRefnumFileName(name, refnum)
char *name;
int refnum;
{
int result;
FCBPBRec pb;
pb.ioCompletion = 0;
pb.ioVRefNum = 0;
pb.ioRefNum = (short)refnum;
pb.ioNamePtr = (unsigned char *)name;
pb.ioFCBIndx = 0;
result = PBGetFCBInfo( &pb, FALSE );
return result;
}
filter_C_string(into, from)
char *into;
char *from;
{
char *ptr;
ptr = into;
for ( ; *from ; )
{
if (*from == '\\')
{
switch (*(from + 1))
{
case '\\':
*ptr++ = '\\';
from += 2;
break;
case 'r':
*ptr++ = '\015';
from += 2;
break;
case 'n':
*ptr++ = '\012';
from += 2;
break;
case 't':
*ptr++ = '\011';
from += 2;
break;
default:
if (isdigit(*(from+1)) &&
isdigit(*(from+2)) &&
isdigit(*(from+3)))
{
*ptr = ((*(from+1) - '0') * 64) +
((*(from+2) - '0') * 8) +
(*(from+3) - '0');
ptr++; from += 4;
}
else
{
*ptr++ = *from++;
}
break;
}
}
else
{
*ptr++ = *from++;
}
}
*ptr = '\0';
return (int)(ptr - into);
}
int
TclMac_ReadEnvInitFile( char * filename )
{
char *ptr;
FILE *infile;
char input[512];
char filtered[512];
infile = fopen(filename, "r");
if (infile != NULL)
{
for ( ; fgets(input, sizeof(input)-1, infile) != NULL ; )
{
if (input[strlen(input)-1] == '\015')
input[strlen(input)-1] = '\0';
if (input[strlen(input)-1] == '\012')
input[strlen(input)-1] = '\0';
for (ptr=input; *ptr && *ptr != '='; ptr++)
;
if (*ptr == '=')
{
*ptr = '\0';
filter_C_string(filtered, ptr + 1);
TclSetEnv(input, filtered);
*ptr = '=';
}
}
fclose(infile);
}
return TCL_OK;
}
int
TclMac_InitializeOnce(app_refnum)
short app_refnum;
{
_tclmac_apprenum_ = app_refnum;
TclMac_InitializeEnvironment(app_refnum);
TclMac_ReadEnvInitFile("•tclenv");
return TCL_OK;
}
int
TclMac_InitializeEnvironment(app_refnum)
short app_refnum;
{
short vRefNum,
myerr,
has_find_folder;
long dirID,
gestaltLong;
char pathbuf[1024],
user_name[256],
*ptr;
Str32 app_fname;
Tcl_DString pathStr;
get_user_name(user_name);
TclSetEnv(kLoginnameTag, user_name);
TclMac_CWDPathName(pathbuf);
tcl_check_path_termination(pathbuf);
TclSetEnv(kDefaultDirTag, pathbuf);
GetRefnumFileName((char *)app_fname, app_refnum);
p2cstr((char *)app_fname);
TclSetEnv(kAppFileNameTag, (char *)app_fname);
c2pstr((char *)app_fname);
GetRefnumPathName(pathbuf, app_refnum);
tcl_check_path_termination(pathbuf);
TclSetEnv(kApplicationDirTag, pathbuf);
Tcl_DStringInit(&pathStr);
Tcl_DStringAppendElement(&pathStr, pathbuf);
TclSetEnv(kDirPathTag, pathStr.string);
Tcl_DStringFree(&pathStr);
strcat(pathbuf, ":");
strcat(pathbuf, user_name);
TclSetEnv(kHomeDirTag, pathbuf);
has_find_folder = 0;
if (GestaltAvailable())
{
myerr = Gestalt(gestaltFindFolderAttr, &gestaltLong);
if (myerr == noErr)
if ((gestaltLong & (1 << gestaltFindFolderPresent)) != 0)
has_find_folder = 1;
}
if ( has_find_folder )
{
myerr = FindFolder( kOnSystemDisk, kSystemFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kSysFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kDesktopFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kDeskFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kTrashFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kTrashFolderTag, pathbuf);
TclSetEnv(kShTrashFolderTag, pathbuf); /* ??? */
myerr = FindFolder( kOnSystemDisk, kPrintMonitorDocsFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kPrintMonFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kStartupFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kStartUpFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kAppleMenuFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kAppleMenuFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kControlPanelFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kCPFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kExtensionFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kExtFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kPreferencesFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kPrefFolderTag, pathbuf);
myerr = FindFolder( kOnSystemDisk, kTemporaryFolderType,
TRUE, &vRefNum, &dirID );
dirpathname(pathbuf, vRefNum, dirID);
tcl_check_path_termination(pathbuf);
TclSetEnv(kTempFolderTag, pathbuf);
}
else
{
vRefNum = BlessedWD();
pathname(pathbuf, vRefNum);
tcl_check_path_termination(pathbuf);
TclSetEnv(kSysFolderTag, pathbuf);
ptr = pathbuf + strlen(pathbuf);
strcpy(ptr, "Preferences:");
TclSetEnv(kPrefFolderTag, pathbuf);
strcpy(ptr, "Extensions:");
TclSetEnv(kExtFolderTag, pathbuf);
strcpy(ptr, "Control Panels:");
TclSetEnv(kCPFolderTag, pathbuf);
strcpy(ptr, "Apple Menu Items:");
TclSetEnv(kAppleMenuFolderTag, pathbuf);
strcpy(ptr, "PrintMonitor Documents:");
TclSetEnv(kPrintMonFolderTag, pathbuf);
strcpy(ptr, "Startup Items:");
TclSetEnv(kStartUpFolderTag, pathbuf);
ptr = strchr(pathbuf, ':');
if (ptr != NULL)
{
strcpy( ptr + 1, "Trash:");
TclSetEnv(kTrashFolderTag, pathbuf);
TclSetEnv(kShTrashFolderTag, pathbuf); /* ??? */
strcpy( ptr + 1, "Desktop Folder:");
TclSetEnv(kDeskFolderTag, pathbuf);
strcpy( ptr + 1, "Temporary Items:");
TclSetEnv(kTempFolderTag, pathbuf);
}
}
get_machine_name(pathbuf);
TclSetEnv(kMachineNameTag, pathbuf);
get_system_version(pathbuf);
TclSetEnv(kSystemVersionTag, pathbuf);
return TCL_OK;
}
int
Tcl_AddMacintoshCmds(interp)
Tcl_Interp *interp;
{
Tcl_CreateCommand(interp, "beep", Mac_BeepCmd,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cd", TclMac_CD,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cp", TclMac_CopyFile,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "ctime", TclMac_CTime,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "cvttime", TclMac_CvtTime,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "echo", TclMac_Echo,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "getfinfo", TclMac_GetFileInfo,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "isalias", TclMac_IsAliasFile,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "ls", TclMac_LS,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "mkdir", TclMac_MkDir,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "mtime", TclMac_DateTime,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "mv", TclMac_MoveFile,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "now", TclMac_Now,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "pwd", TclMac_PWD,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "resolve_alias", TclMac_ResolveAlias,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "rm", TclMac_RM,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "rmdir", TclMac_RmDir,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "setfinfo", TclMac_SetFileInfo,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "ticks", TclMac_Ticks,
(ClientData)NULL, (void (*)())NULL);
Tcl_CreateCommand(interp, "source", Mac_SourceCmd,
(ClientData)NULL, (void (*)())NULL);
return TCL_OK;
}
int
Tcl_InitMacintosh(interp)
Tcl_Interp *interp;
{
int result;
char command[128];
/* UNDONE - error handling */
sprintf(command, "set MACINTOSH 1\n");
result = Tcl_Eval(interp, command);
sprintf(command, "set MAC_TCL 1\n");
result = Tcl_Eval(interp, command);
#ifdef TCLENGINE
sprintf(command, "set tcl_interactive 0\n");
#else
sprintf(command, "set tcl_interactive 1\n");
#endif
result = Tcl_Eval(interp, command);
return TCL_OK;
}
int
NumToolboxTraps()
{
if ( NGetTrapAddress(_InitGraf, ToolTrap)
== NGetTrapAddress(0xAA6E, ToolTrap) )
return 0x0200;
else
return 0x0400;
}
TrapType
GetTrapType(short theTrap)
{
#define TrapMask 0x0800
if ((theTrap & TrapMask) != 0)
return ToolTrap;
else
return OSTrap;
}
TrapAvailable(short theTrap)
{
TrapType tType;
tType = GetTrapType(theTrap);
if (tType == ToolTrap)
{
theTrap &= 0x07FF;
if ( theTrap >= NumToolboxTraps() )
theTrap = _Unimplemented;
}
return NGetTrapAddress(theTrap, tType) !=
NGetTrapAddress(_Unimplemented, ToolTrap);
}
WNEAvailable()
{
return TrapAvailable(_WaitNextEvent);
}
GestaltAvailable()
{
return TrapAvailable(0xA1AD);
}
int
TclMac_User_Wants_Break(interp)
Tcl_Interp *interp;
{
if (_tclmac_user_interrupt_)
{
Tcl_AppendResult(interp, " *** user interrupt *** ", (char *)0);
_tclmac_user_interrupt_ = 0;
return 1;
}
return 0;
}
#ifdef EXAMPLE_SOURCE
check_environment_set_of_globals(name, value)
char *name;
char *value;
{
}
#endif